﻿#include "KSynthesisMin1.h"
#include "Tools.h"
#include "CTPTime.h"

KSynthesisMin1::KSynthesisMin1(const std::string &pSymbol) : KSynthesisBase(pSymbol)
{
}

KSynthesisMin1::~KSynthesisMin1()
{
}

void KSynthesisMin1::SynthesisFrmList(const std::deque<MData::KLineItem> &frmKItems, std::deque<MData::KLineItem> &outKItems)
{
	std::deque<MData::KLineItem> newKItems;
	if (frmKItems.empty())
	{
		outKItems.swap(newKItems);
		return;
	}
	//// 前两个K线单独判断（其实这里并不准确）
	//const MData::KLineItem &tmpSrcKItem1 = frmKItems.at(0);
	//bool kfull = isSrcKItemFull(tmpSrcKItem1);
	//if (kfull)
	//{
	//	newKItems.emplace_back(tmpSrcKItem1);
	//	if (frmKItems.size() < 2)
	//	{
	//		outKItems.swap(newKItems);
	//		return;
	//	}
	//	newKItems.emplace_back(frmKItems.at(1));
	//}
	//else // 合并到下一根K线里面
	//{
	//	if (frmKItems.size() < 2)
	//	{
	//		outKItems.swap(newKItems);
	//		return;
	//	}
	//	MData::KLineItem tmpSrcKItem2 = frmKItems.at(0);
	//	tmpSrcKItem2.Open = tmpSrcKItem1.Open;
	//	tmpSrcKItem2.High = std::max(tmpSrcKItem2.High, tmpSrcKItem1.High);
	//	tmpSrcKItem2.Low = std::min(tmpSrcKItem2.Low, tmpSrcKItem1.Low);
	//	newKItems.emplace_back(tmpSrcKItem2);
	//}

	for (int i = 0; i < frmKItems.size(); ++i)
	{
		const MData::KLineItem &tmpSrcKItem = frmKItems.at(i);
		bool kfull = isSrcKItemFull(tmpSrcKItem);
		if (kfull)
		{
			newKItems.emplace_back(tmpSrcKItem);
			continue;
		}
		// 如果是竞价行情，合并到下一根行情
		if (IsBidingItem(tmpSrcKItem.UpdateTime))
		{
			if (i + 1 < frmKItems.size())
			{
				MData::KLineItem tmpSrcKItemnext = frmKItems.at(i + 1);
				tmpSrcKItemnext.Open = tmpSrcKItem.Open;
				tmpSrcKItemnext.High = std::max(tmpSrcKItem.High, tmpSrcKItemnext.High);
				tmpSrcKItemnext.Low = std::min(tmpSrcKItem.Low, tmpSrcKItemnext.Low);
				newKItems.emplace_back(tmpSrcKItemnext);
				++i; // 往下迭代1
			}
			else
			{
				newKItems.emplace_back(tmpSrcKItem);
			}
			continue;
		}
		bool beMerged = false;
		// 判断与下一根行情的时间距离，如果距离超过了5分钟，则考虑合并
		if (i + 1 < frmKItems.size())
		{
			const MData::KLineItem &tmpSrcKItemnext = frmKItems.at(i + 1);
			if (tmpSrcKItemnext.UpdateTime - tmpSrcKItem.UpdateTime > 300 && !newKItems.empty()) // 要合并到上一根
			{
				MData::KLineItem &lastNewKItem = newKItems.back();
				UpdateCloseValue(lastNewKItem, tmpSrcKItem);
				beMerged = true;
			}
		}
		else if (m_verifyTime > 0)
		{
			if (m_verifyTime - tmpSrcKItem.UpdateTime > 300 && !newKItems.empty()) // 要合并到上一根
			{
				MData::KLineItem &lastNewKItem = newKItems.back();
				UpdateCloseValue(lastNewKItem, tmpSrcKItem);
				beMerged = true;
			}
		}
		if (!beMerged)
		{
			newKItems.emplace_back(tmpSrcKItem);
		}
	}
	outKItems.swap(newKItems);
}

void KSynthesisMin1::SynthesisFrmDate(time_t pDate, std::deque<MData::KLineItem> &outKItems)
{
	MDIO::KItem kStream;
	std::deque<MData::KLineItem> srcKItems;
	kStream.ReadKItemsInDays(m_symbolName, pDate, pDate, srcKItems);
	SynthesisFrmList(srcKItems, outKItems);
}

void KSynthesisMin1::SynthesisFrmRange(time_t frmTime, time_t endTime, std::deque<MData::KLineItem> &outKItems)
{
	std::vector<time_t> pDays;
	CTPTm::DateRangeToDays(frmTime, endTime, pDays);
	for (int iDay = 0; iDay < pDays.size(); ++iDay)
	{
		std::deque<MData::KLineItem> pKItems;
		SynthesisFrmDate(pDays.at(iDay), pKItems);
		for (std::deque<MData::KLineItem>::iterator it = pKItems.begin(); it != pKItems.end(); ++it)
		{
			if (it->UpdateTime < frmTime)
			{
				continue;
			}
			if (it->UpdateTime > endTime)
			{
				break;
			}
			outKItems.emplace_back(*it);
		}
	}
}

void KSynthesisMin1::SynthesisFrmTime(time_t pTime, MData::KLineItem &outKItem)
{
	outKItem.UpdateTime = 0;
	// 上调1分，下调1分，取这个时间范围内的K线
	MDIO::KItem kStream;
	std::deque<MData::KLineItem> srcKItems;
	time_t beginTime = pTime - 60;
	time_t endTime = pTime + 60;
	kStream.ReadKItemsInTimes(m_symbolName, beginTime, endTime, srcKItems);
	if (srcKItems.empty())
	{
		return;
	}
	// K线的时间范围
	time_t beginKTime = 0, endKTime = 0;
	getKItemRange(pTime, beginKTime, endKTime);

	std::deque<MData::KLineItem> nKItems;
	GetMinuteKItems(srcKItems, beginKTime, endKTime, nKItems);
	if (nKItems.empty())
	{
		return;
	}
	// 理论上这里应该只有1根K线
	outKItem = nKItems.front();
}

bool KSynthesisMin1::IsThisKItemFinished(time_t pLaskKUpdateTime, time_t curTime)
{
	return pLaskKUpdateTime > 0;
}

void KSynthesisMin1::getKItemRange(time_t pUpdateTime, time_t &outKItemBegin, time_t &outKItemEnd)
{
	tm pDataTime = Tools::GetDateTimeFrmStamp(pUpdateTime);

	pDataTime.tm_sec = 0;
	outKItemBegin = Tools::GetTimeStamp(pDataTime);

	pDataTime.tm_sec = 59;
	outKItemEnd = Tools::GetTimeStamp(pDataTime);
}